package model;

import java.util.HashMap;
import java.util.regex.Pattern;

import persistence.PersistenceManager;

/**
 * 
 * Filter, a place holder for all the filter inputs
 *
 */
public class Filter implements FilterImp, Comparable<Filter>
{
	
	private String filterName;
	private String keywordToSearch = "";
	private String destination;
	private String receiver = "";
	private boolean enabled = false;
	private boolean senderSearchFound = false;
	private boolean domainSearchFound = false;
    private String fileName = "";
    private int priority = 0;
    private boolean searchInSubject = false;
    private boolean searchInMessage = false;

    /**
     * Constructor
     */
    public Filter()
    {
 
    }
	
    /**
     * Constructor
     * @param name the name of the filter
     */
	public Filter(String name)
	{
		this.filterName = name;
	}
	
	/**
	 * Constructor
	 * @param name name the name of the filter
	 * @param keywordToSearch keyword to search
	 * @param destination destination folder for email to move
	 * @param receiver the user from which the email has been received
	 */
	public Filter(String name, String keywordToSearch, String destination,String receiver)
	{
		this.filterName = name;
		this.keywordToSearch = keywordToSearch;
		this.destination = destination;
		this.receiver = receiver;
		
	}
	    
	    /**
	     * check if the search the keyword in subject is enabled
	     * @return return the variable status (true/false)
	     */
	    public boolean isSearchInSubject()
	    {
	        return searchInSubject;
	    }

	    /**
	     * set the search in subject boolean variable to the given state (true/false)
	     * @param searchInSubject boolean value true or false
	     */
	    public void setSearchInSubject(boolean searchInSubject)
	    {
	        this.searchInSubject = searchInSubject;
	    }

	    /**
         * check if the search the keyword in message is enabled
	     * @return return the variable status (true/false)
	     */
	    public boolean isSearchInMessage()
	    {
	        return searchInMessage;
	    }

	    /**
         * set the search in message boolean variable to the given state (true/false)
         * @param searchInMessage boolean value true or false
         */
	    public void setSearchInMessage(boolean searchInMessage)
	    {
	        this.searchInMessage = searchInMessage;
	    }
	
	/**
	 * get the receiver of the email
	 * @return the receiver of the email
	 */
	public String getReceiver()
	{
		return receiver;	
	}
	
	/**
	 * set receiver of the email
	 * @param receiver the receiver of the email
	 */
	public void setReceiver(String receiver)
	{
		this.receiver = receiver;
	}
	
	/**
	 * get keyword to search
	 * @return Return the keyword to search
	 */
	public String getKeywordToSearch()
	{
	    return keywordToSearch;
	}

	/*
	 * (non-Javadoc)
	 * @see model.FilterImp#isFromSender(java.util.HashMap, java.lang.String)
	 */
	public boolean isFromSender(HashMap<String, String> arrivedEmail, String sender) 
	{
		senderSearchFound = (arrivedEmail.get("sender").equalsIgnoreCase(sender)); 
		return senderSearchFound;
	}

	/*
	 * (non-Javadoc)
	 * @see model.FilterImp#isFromDomain(java.util.HashMap, java.lang.String)
	 */
	public boolean isFromDomain(HashMap<String, String> arrivedEmail,String domain) {
		String emailDomain = arrivedEmail.get("sender").split("@")[1];
		domainSearchFound = (emailDomain.equalsIgnoreCase(domain));
		return domainSearchFound;
	}

	/*
	 * (non-Javadoc)
	 * @see model.FilterImp#hasWords(java.util.HashMap, java.lang.String)
	 */
	public boolean hasWords(HashMap<String, String> arrivedEmail, String wordsSeparatedByCommas) {
		
		String [] wordList = wordsSeparatedByCommas.split(",");
		
		for(String query:wordList)
			{
					Pattern searchPattern = Pattern.compile("(?=.*"+query.trim()+".*)", Pattern.CASE_INSENSITIVE);
					if(	searchPattern.matcher(arrivedEmail.get("subject")).find() || 
							searchPattern.matcher(arrivedEmail.get("message")).find())
					{
						return true;
					}
			}
		
		return false;
	}
	
   /**
    * check if the given search word(s) are present in the subject of the given email
    * @param email the email
    * @param wordsSeparatedByCommas the word(s) to search which are comma separated
    * @return returns return if found, else false
    */
   public boolean hasWordsInSubject(HashMap<String, String> email, String wordsSeparatedByCommas)
   {
        
        String [] wordList = wordsSeparatedByCommas.split(",");
        
        for(String query:wordList)
            {
                    Pattern searchPattern = Pattern.compile("(?=.*"+query.trim()+".*)", Pattern.CASE_INSENSITIVE);
                    if( searchPattern.matcher(email.get("subject")).find())
                    {
                        return true;
                    }
            }
        
        return false;
    }
   
   /**
    * check if the given search word(s) are present in the message of the given email
    * @param email the email
    * @param wordsSeparatedByCommas the word(s) to search which are comma separated
    * @return returns return if found, else false
    */
   public boolean hasWordsInMessage(HashMap<String, String> email, String wordsSeparatedByCommas) {
       
       String [] wordList = wordsSeparatedByCommas.split(",");
       
       for(String query:wordList)
           {
                   Pattern searchPattern = Pattern.compile("(?=.*"+query.trim()+".*)", Pattern.CASE_INSENSITIVE);
                   if(searchPattern.matcher(email.get("message")).find())
                   {
                       return true;
                   }
           }
       
       return false;
   }
	
   /**
    * get the priority of the filter
    * @return the value of the priority ( Close towards the 1, the more priority, the priority is.)
    */
	public int getPriority()
    {
        return priority;
    }

	/**
	 * set the priority
	 * @param priority the value of the priority ( Close towards the 1, the more priority, the priority is.)
	 */
    public void setPriority(int priority)
    {
        this.priority = priority;
    }

	/*
	 * (non-Javadoc)
	 * @see model.FilterImp#isEnabled()
	 */
	public boolean isEnabled() {
		return enabled;
	}

	/*
	 * (non-Javadoc)
	 * @see model.FilterImp#setActivation(boolean)
	 */
	public void setActivation(boolean enable) {
		this.enabled=enable;

	}
	
	/**
	 * get destination folder for email to move
	 * @return
	 */
	public String getDestination()
	{
		return this.destination;
	}
	
	/**
	 * set destination folder for email to move
	 * @param destination
	 */
	public void setDestination(String destination)
	{
		this.destination = destination;
	}
	
	/**
	 * get the name of the filter
	 * @return return the name of the filter
	 */
	public String getFilterName()
    {
        return this.filterName; 
    }

	/**
	 * get the name of the filer, the spaces are replaced by comma
	 * @return return the name of the filer, the spaces are replaced by comma
	 */
	public String getFileName()
	{
	    fileName = this.filterName.replaceAll("\\s", "_");
	    return fileName; 
	}

    /*
     * (non-Javadoc)
     * @see java.lang.Comparable#compareTo(java.lang.Object)
     */
    public int compareTo(Filter otherFilter)
    {
        return ((Integer)priority).compareTo(otherFilter.priority);
    }

    /**
     * is search found based on the filter criteria in the email, from the given email path
     * @param emailFilePath email file path
     * @return Return the email(s) that are passed by the filter
     */
    public boolean isSearchFound(String emailFilePath)
    {
    	PersistenceManager pers = new PersistenceManager();
    	boolean isFoundFromSender = false;
    	boolean hasWordsInSubject = false;
    	boolean hasWordsInMessage = false;
    	
    	HashMap<String, String> email = pers.emailJsonToMap(emailFilePath);
    	
    	if(! "".equals(email.get("sender")) )
    	{
            isFoundFromSender =  this.isFromSender(email, receiver);    
    	}
    	
    	if(searchInSubject)
    	{
    	    hasWordsInSubject = this.hasWordsInSubject(email, keywordToSearch);
    	}
    	
    	if(searchInMessage)
    	{
    	    hasWordsInMessage = this.hasWordsInMessage(email, keywordToSearch);
    	}
    	
    	if(searchInSubject && searchInMessage)
    	{
    	    hasWordsInSubject = this.hasWordsInSubject(email, keywordToSearch);
            hasWordsInMessage = this.hasWordsInMessage(email, keywordToSearch);
    	}
    	
    	return (isFoundFromSender || hasWordsInSubject || hasWordsInMessage);
    }

}
